﻿
using JinYuan.CommunicationLib.Enum;
using JinYuan.DataConvertLib;
using JinYuan.Helper;
using JinYuan.MES.Models;
using JinYuan.Models;
using JinYuan.VirtualDataLibrary;
using Newtonsoft.Json;
using PLCCommunication;
using SqlSugar;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace JinYuan.ControlCenters
{
    public partial class ControlCenter
    {
        private static LoggerHelp _logger = new LoggerHelp();
        /// <summary>
        /// 打印日志方法
        /// </summary>
        /// <param name="Message"></param>日志信息
        /// <param name="FileName"></param>文件夹名字
        public static void LogMessage(string Message, string FileName)
        {
            string filePath = FileName + "//" + DateTime.Now.ToString("yyyy-MM-dd"); // 日志文件存放路径，默认在debug目录下
            string filePath2 = FileName + "//" + DateTime.Now.ToString("yyyy-MM-dd") + "//Mylog.txt";//也可以加上时间
                                                                                                     //string file=DateTime.Now+"log.txt";
                                                                                                     //检查文件夹是否存在，否则新建
            if (!Directory.Exists(filePath))
            {
                Directory.CreateDirectory(filePath);
            }
            string logMessage = $"{DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}: {Message}";//打印出现的时间
                                                                                                 // 将消息写入日志文件
            using (StreamWriter writer = new StreamWriter(filePath2, true))
            {
                writer.WriteLine(logMessage);
            }
        }

        /// <summary>
        /// 打印错误日志方法
        /// </summary>
        /// <param name="errorMessage"></param>
        public static void LogErrorMessage(string errorMessage)
        {
            string filePath = "Mylog.txt"; // 日志文件存放路径，默认在debug目录下
                                           //也可以加上时间
                                           //string file=DateTime.Now+"log.txt";
            string logMessage = $"{DateTime.Now}: {errorMessage}";//打印出现问题的时间
                                                                  // 将错误消息写入日志文件
            using (StreamWriter writer = new StreamWriter(filePath, true))
            {
                writer.WriteLine(logMessage);
            }
        }

        private static object uiLock = new object();

        private Dictionary<string, dgStationFunction> DicStationFunction;
        /// <summary>
        /// 定时器-定时刷新状态和数据
        /// </summary>
        private System.Timers.Timer Timer_RefreshData;
        /// <summary>
        /// 智能电表
        /// </summary>
        private System.Timers.Timer ProcessMeter = null;
        //创建委托对象
        private Action<SysLog> AddAlarmDelegate;
        //创建实时报警集合
        private ObservableCollection<string> actualAlarmList = new ObservableCollection<string>();

        //所有归档变量的名称l集合
        private List<string> varNameList;

        /// <summary>
        /// 窗体实例
        /// </summary>
        private static ControlCenter _instance;
        public static ControlCenter Instance
        {
            get
            {
                lock (uiLock)
                {
                    if (_instance == null)
                    {
                        _instance = new ControlCenter();
                    }
                    return _instance;
                }
            }
        }

        private ControlCenter()
        {

            GetAlarmData();
            InitFunc();
            IntiDevice();
            Timer_RefreshData = new System.Timers.Timer(1000);
            Timer_RefreshData.Elapsed += Timer_RefreshData_Elapsed;
            Timer_RefreshData.Start();

            //删除30天内日志
            DeleteLog.Start(CommonMethods.strDeletepath);

            if (!CommonMethods.IsRun)
            {
                CommonMethods.ResetEventRecv.Reset();
            }
        }




        /// <summary>
        /// 初始化 工位方法，添加到字典里面
        /// </summary>
        private void InitFunc()
        {
            DicStationFunction = new Dictionary<string, dgStationFunction>();

            DicStationFunction.Add("电芯进站", FeedingStation);
           // DicStationFunction.Add("NG出站", NGStation);
            DicStationFunction.Add("电芯出站", BlankingStation);

            for (int i = 0; i < CommonMethods.ChatLineCount; i++)
            {
                Queue<double> doubles = new Queue<double>();
                CommonMethods.QPlanenessData.Add(doubles);
            }
        }
        public static string devPath = Application.StartupPath + "\\Config\\Device.ini";
        public static string groupPath = Application.StartupPath + "\\Config\\Group.xlsx";
        public static string variablePath = Application.StartupPath + "\\Config\\Variable.xlsx";

        #region PLC
        public void IntiDevice()
        {

            //var result = GetDeviceByPath(CommonMethods.settingPath);
            var result = LoadDevice(devPath, groupPath, variablePath);
            if (result.IsSuccess)
            {
                //获取到设备对象
                CommonMethods.plcDevice = result.Content;
                //设置一下大小端
                CommonMethods.plcDevice.DataFormat = (int)DataFormat.CDAB;
                //初始化

                CommonMethods.plcDevice.Init();
                //报警处理
                //CommonMethods.plcDevice.AlarmTriggerEvent += PlcDevice_AlarmTriggerEvent;
                //开启多线程
                CommonMethods.plcDevice.Cts = new CancellationTokenSource();
                //按工位读取通信组
                CommonMethods.ListOmronGroups = CommonMethods.plcDevice.WorkVarList;
                //风速仪器
                //CommonMethods.AntiDustAirSpeed = GetList<float>(1);

                //按工位读取数据线程
                CreatePLCThread();
            }
            else
            {
                CommonMethods.AddLog(true, "加载配置文件失败：" + result.Message);
            }
        }

        private void PlcDevice_AlarmTriggerEvent(object sender, AlarmEventArgs e)
        {

            switch (actualAlarmList.Count)
            {
                case 0:
                    CommonMethods.SlideAlarmText = "当前无报警";
                    break;
                default:
                    CommonMethods.SlideAlarmText = string.Join(" ", actualAlarmList);
                    break;
            }
        }

        #region 创建PLC线程 几个工位就几个线程

        /// <summary>
        /// 按工位读取线程
        /// </summary>
        private void CreatePLCThread()
        {
            //开启工位读取线程
            if (CommonMethods.ListOmronGroups != null)
            {
                foreach (var item in CommonMethods.ListOmronGroups)
                {
                    if (item.IsActive)
                    {
                        Thread thread = new Thread(new ParameterizedThreadStart(ReadPLCMWorkModel));
                        thread.IsBackground = true;
                        thread.Priority = ThreadPriority.Highest;
                        thread.Start(item);
                    }
                }
            }

            //开启循环读取线程
            Task.Run(new Action(() =>
            {
                PLCCommunication(CommonMethods.plcDevice);
            }), CommonMethods.plcDevice.Cts.Token);

            //开启监控焊机功率
            //GetDataFromDatabasePower();
        }
        #endregion

        #region 循环读取PLC工位状态
        /// <summary>
        /// 读取PLC循环工位
        /// </summary>
        /// <param name="plcModel"></param>
        /// 
        Stopwatch sw1 = new Stopwatch();
        Stopwatch sw3 = new Stopwatch();
        private void ReadPLCMWorkModel(object plcModel)
        {
            //as 类型转换
            Group pf = plcModel as Group;
            bool sta = CommonMethods.IsExit;
            while (!CommonMethods.IsExit)
            {
                CommonMethods.ResetEventRecv.WaitOne();
                if (CommonMethods.IsRun)
                {
                    if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
                    {
                        try
                        {
                            //开始读取信号判断
                            JYResult<short> OpenValue = CommonMethods.PlcLink.ReadValue<JYResult<short>>(pf.VarList[0].VarAddress, Data_Type.Short);//当读取值为就执行操作
                            if (OpenValue.IsSuccess && OpenValue.Content == 1)//读取先置位 
                            {
                                sw1.Restart();
                                JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>($"{pf.VarList[1].VarAddress}", Data_Type.ArrByte, Convert.ToUInt16(pf.VarList[1].OffsetOrLenght));
                                sw1.Stop();
                                CommonMethods.AddDataMonitorLog(0, $"{pf.GroupName},耗时：{sw1.Elapsed.TotalMilliseconds}ms");
                                LoggerHelp.WriteLog("循环读取PLC工位" + $"读取工位:{pf.GroupName},启动读取字节共耗时：" + sw1.Elapsed.TotalMilliseconds);
                                //置位  PLC-防止重复读取
                                CommonMethods.PlcLink.WriteInt16(pf.VarList[0].VarAddress, 2);//置位，读取进行中的标志

                                if (resByte == null)
                                {
                                    CommonMethods.AddDataMonitorLog(0, $"上料工位:{pf.GroupName},起始地址:{pf.VarList[1].VarAddress},得到空字节数组");
                                    LoggerHelp.WriteLog("循环读取PLC上料工位" + $"读取工位:{pf.GroupName},起始地址:{pf.VarList[1].VarAddress},得到空字节数组");
                                }
                                else
                                {
                                    //if (DicStationFunction.TryGetValue(pf.GroupName, out var func))
                                    //{
                                    //    func.BeginInvoke(resByte, pf, ar =>
                                    //    {
                                    //        try { func.EndInvoke(ar); }
                                    //        catch (Exception ex)
                                    //        {
                                    //            CommonMethods.AddLog(true, ex.Message);
                                    //            LogHelper.Instance.WriteEX(ex);
                                    //        }
                                    //    }, null);
                                    //}
                                    //// private Dictionary<string, dgStationFunction> DicStationFunction;
                                    DicStationFunction[pf.GroupName].BeginInvoke(resByte, pf, null, null);//信息解析
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            CommonMethods.AddLog(true, ex.Message);
                            LoggerHelp.WriteEX(ex);
                        }
                    }
                    Thread.Sleep(200);
                }
            }
        }
        #endregion

        private void PLCCommunication(Device device)
        {
            while (!CommonMethods.plcDevice.Cts.IsCancellationRequested)
            {
                CommonMethods.ResetEventRecv.WaitOne();
                if (CommonMethods.IsRun)
                {
                    if (device.IsConnected)
                    {
                        //读取
                        //LogErrorMessage("Ready read 1 s");
                        JYResult<short> result = CommonMethods.PlcLink.ReadValue<JYResult<short>>("D100", Data_Type.Short);
                        if (result.IsSuccess)
                        {
                            //if(result.Content == 0)
                            {
                                //延时2s发送心跳
                                Thread.Sleep(2000);
                                //LogErrorMessage("Ready write");
                                device.ErrorTimes = 0;
                                JYResult res = CommonMethods.PlcLink.WriteValue("D100", 1, Data_Type.Short);
                                if (!res.IsSuccess)
                                {
                                    device.IsConnected = false;
                                    CommonMethods.AddLog(true, "心跳写入异常：" + res.Message);
                                }
                                //LogErrorMessage("Write done");
                            }

                        }
                        else
                        {
                            device.ErrorTimes++;
                            //容错次数的意思是指连续多少次错误，会触发重连（连续3次）
                            if (device.ErrorTimes >= device.AllowErrorTimes)
                            {
                                device.IsConnected = false;
                                CommonMethods.AddLog(true, "PLC链接异常：" + result.Message);
                                break;
                            }
                        }
                    }
                    else
                    {
                        //判断是否为第一次连接
                        if (!device.IsFirstConnect)
                        {
                            Thread.Sleep(device.ReConnectTime);
                            CommonMethods.PlcLink.Disconnect();
                        }
                        string msg = "";
                        var result = CommonMethods.PlcLink.Connect(ref msg);
                        if (result)
                        {
                            device.IsConnected = true;
                            CommonMethods.AddLog(false, device.IsFirstConnect ? $"PLC初次连接成功{msg}" : $"PLC重新连接成功{msg}");
                        }
                        else
                        {
                            device.IsConnected = false;
                            CommonMethods.AddLog(true, device.IsFirstConnect ? "PLC初次连接失败" : "PLC重新连接失败");
                            new MsgshowTip("与PLC链接断开，请检查通讯线路！").ShowDialog();
                        }
                    }
                    //如果是第一次连接，将标志位复位
                    if (device.IsFirstConnect)
                    {
                        device.IsFirstConnect = false;
                    }
                }
            }
        }


        #region 屏蔽 
        /// <summary>
        /// 多线程执行方法
        /// </summary>
        /// <param name="plcDevice"></param>
        //private void PLCCommunication(OmronDevice device)
        //{
        //    while (!CommonMethods.plcDevice.Cts.IsCancellationRequested)
        //    {
        //        CommonMethods.ResetEventRecv.WaitOne();
        //        if (CommonMethods.IsRun)
        //        {
        //            if (device.IsConnected)
        //            {
        //                //读取
        //                foreach (var gp in device.GroupList)
        //                {
        //                    if (gp.IsActive)
        //                    {
        //                        if (!gp.IsWorkRead)
        //                        {
        //                            var result = GetGroupValue(device, gp);
        //                            if (result.IsSuccess)
        //                            {
        //                                device.ErrorTimes = 0;
        //                            }
        //                            else
        //                            {
        //                                device.ErrorTimes++;
        //                                //容错次数的意思是指连续多少次错误，会触发重连
        //                                if (device.ErrorTimes >= device.AllowErrorTimes)
        //                                {
        //                                    device.IsConnected = false;
        //                                    CommonMethods.AddLog(true, "PLC链接异常：" + result.Message);
        //                                    break;
        //                                }
        //                            }
        //                        }

        //                    }
        //                    Thread.Sleep(50);
        //                }
        //            }
        //            else
        //            {
        //                //判断是否为第一次连接
        //                if (!device.IsFirstConnect)
        //                {
        //                    Thread.Sleep(device.ReConnectTime);
        //                    CommonMethods.plc.DisConnect();
        //                }
        //                byte[] bytes = null;
        //                var result = CommonMethods.plc.Connect(device.IpAddress, device.Port, ref bytes);
        //                if (result)
        //                {
        //                    device.IsConnected = true;
        //                    CommonMethods.AddLog(false, device.IsFirstConnect ? $"PLC初次连接成功:SA1-{bytes[0]},DA1-{bytes[1]}" : $"PLC重新连接成功:SA1-{bytes[0]},DA1-{bytes[1]}");
        //                }
        //                else
        //                {
        //                    device.IsConnected = false;
        //                    CommonMethods.AddLog(true, device.IsFirstConnect ? "PLC初次连接失败" : "PLC重新连接失败");
        //                    new MsgshowTip("与PLC链接断开，请检查通讯线路！").ShowDialog();
        //                }
        //            }
        //            //如果是第一次连接，将标志位复位
        //            if (device.IsFirstConnect)
        //            {
        //                device.IsFirstConnect = false;
        //            }
        //        }
        //    }
        //}


        //private void PLCCommunication(Device device)
        //{
        //    while (!CommonMethods.plcDevice.Cts.IsCancellationRequested)
        //    {
        //        CommonMethods.ResetEventRecv.WaitOne();
        //        if (CommonMethods.IsRun)
        //        {
        //            if (device.IsConnected)
        //            {
        //                读取
        //                foreach (var gp in device.GroupList)
        //                {
        //                    if (gp.IsActive)
        //                    {
        //                        if (!gp.IsTiggerRead)
        //                        {
        //                            var result = GetHSLGroupValue(device, gp);
        //                            if (result.IsSuccess)
        //                            {
        //                                device.ErrorTimes = 0;
        //                            }
        //                            else
        //                            {
        //                                device.ErrorTimes++;
        //                                容错次数的意思是指连续多少次错误，会触发重连
        //                                if (device.ErrorTimes >= device.AllowErrorTimes)
        //                                {
        //                                    device.IsConnected = false;
        //                                    CommonMethods.AddLog(true, "PLC链接异常：" + result.Message);
        //                                    break;
        //                                }
        //                            }
        //                        }

        //                    }
        //                }
        //            }
        //            else
        //            {
        //                判断是否为第一次连接
        //                if (!device.IsFirstConnect)
        //                {
        //                    Thread.Sleep(device.ReConnectTime);
        //                    CommonMethods.PlcLink.Disconnect();
        //                }
        //                string msg = "";
        //                var result = CommonMethods.PlcLink.Connect(ref msg);
        //                if (result)
        //                {
        //                    device.IsConnected = true;
        //                    CommonMethods.AddLog(false, device.IsFirstConnect ? $"PLC初次连接成功{msg}" : $"PLC重新连接成功{msg}");
        //                }
        //                else
        //                {
        //                    device.IsConnected = false;
        //                    CommonMethods.AddLog(true, device.IsFirstConnect ? "PLC初次连接失败" : "PLC重新连接失败");
        //                    new MsgshowTip("与PLC链接断开，请检查通讯线路！").ShowDialog();
        //                }
        //            }
        //            如果是第一次连接，将标志位复位
        //            if (device.IsFirstConnect)
        //            {
        //                device.IsFirstConnect = false;
        //            }
        //        }
        //    }
        //}



        //private OperateResult GetHSLGroupValue(Device device, Group group)
        //{
        //    var addResult = OmronHelper.OmronFinsAnalysisAddress(group.Start, false);

        //    if (addResult.IsSuccess == false) return OperateResult.CreateFailResult();

        //    var result = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>(group.Start, Data_Type.ArrByte, (ushort)group.Length);

        //    if (result.IsSuccess && result.Content.Length == group.Length * 2)
        //    {
        //        foreach (var variable in group.VarList)
        //        {
        //            var analysis = AnalysisStartAddress(variable.Start);

        //            if (analysis.IsSuccess)
        //            {
        //                int start = analysis.Content1;
        //                int offset = analysis.Content2;

        //                start -= BitConverter.ToInt16(new byte[] { addResult.Content2[1], addResult.Content2[0], addResult.Content2[2] }, 0);

        //                start *= 2;

        //                switch (variable.DataType.ToUpper())
        //                {
        //                    case "BOOL":
        //                        variable.VarValue = BitLib.GetBitFrom2BytesArray(result.Content, start, offset, false);
        //                        break;
        //                    case "BYTE":
        //                        variable.VarValue = ByteLib.GetByteFromByteArray(result.Content, start);
        //                        break;
        //                    case "SHORT":
        //                        variable.VarValue = ShortLib.GetShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "USHORT":
        //                        variable.VarValue = UShortLib.GetUShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "INT":
        //                        variable.VarValue = ShortLib.GetShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "UINT":
        //                        variable.VarValue = UIntLib.GetUIntFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "FLOAT":
        //                        variable.VarValue = FloatLib.GetFloatFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "LONG":
        //                        variable.VarValue = LongLib.GetLongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "ULONG":
        //                        variable.VarValue = ULongLib.GetULongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "DOUBLE":
        //                        variable.VarValue = DoubleLib.GetDoubleFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "STRING":
        //                        variable.VarValue = StringLib.GetStringFromByteArrayByEncoding(result.Content, start, (int)variable.Offset * 2, Encoding.ASCII);
        //                        break;
        //                    case "BYTEARRAY":
        //                        variable.VarValue = ByteArrayLib.GetByteArrayFromByteArray(result.Content, start, (int)variable.Offset * 2);
        //                        break;
        //                    default:
        //                        break;
        //                }

        //                var operateResult = MigrationLib.GetMigrationValue(variable.VarValue, variable.Scale.ToString(), variable.Offset.ToString());

        //                if (operateResult.IsSuccess)
        //                {
        //                    variable.VarValue = operateResult.Content;
        //                }
        //                else
        //                {
        //                    variable.VarValue = null;
        //                }

        //                //更新报警
        //                device.Update(variable);
        //            }
        //            else
        //            {
        //                return OperateResult.CreateFailResult(analysis.Message);
        //            }
        //        }
        //    }
        //    else
        //    {
        //        CommonMethods.Statues = new List<bool> { false, false, false, false };
        //        return OperateResult.CreateFailResult($"{group.GroupName}-通信组读取失败");
        //    }
        //    return OperateResult.CreateSuccessResult();
        //}


        /// <summary>
        /// 单个组通信的方法
        /// </summary>
        /// <param name="device"></param>
        /// <param name="group"></param>
        /// <returns></returns>

        //private OperateResult GetGroupValue(Device device, Group group)
        //{
        //    var addResult = OmronHelper.OmronFinsAnalysisAddress(group.Start, false);

        //    if (addResult.IsSuccess == false) return OperateResult.CreateFailResult();

        //    var result = CommonMethods.plc.ReadByteArray(group.Start,(ushort)group.Length);

        //    if (result.IsSuccess && result.Content.Length == group.Length * 2)
        //    {
        //        foreach (var variable in group.VarList)
        //        {
        //            var analysis = AnalysisStartAddress(variable.Start);

        //            if (analysis.IsSuccess)
        //            {
        //                int start = analysis.Content1;
        //                int offset = analysis.Content2;

        //                start -= BitConverter.ToInt16(new byte[] { addResult.Content2[1], addResult.Content2[0], addResult.Content2[2] }, 0);

        //                start *= 2;

        //                switch (variable.DataType.ToUpper())
        //                {
        //                    case "BOOL":
        //                        variable.VarValue = BitLib.GetBitFrom2BytesArray(result.Content, start, offset, false);
        //                        break;
        //                    case "BYTE":
        //                        variable.VarValue = ByteLib.GetByteFromByteArray(result.Content, start);
        //                        break;
        //                    case "SHORT":
        //                        variable.VarValue = ShortLib.GetShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "USHORT":
        //                        variable.VarValue = UShortLib.GetUShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "INT":
        //                        variable.VarValue = ShortLib.GetShortFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "UINT":
        //                        variable.VarValue = UIntLib.GetUIntFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "FLOAT":
        //                        variable.VarValue = FloatLib.GetFloatFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "LONG":
        //                        variable.VarValue = LongLib.GetLongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "ULONG":
        //                        variable.VarValue = ULongLib.GetULongFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "DOUBLE":
        //                        variable.VarValue = DoubleLib.GetDoubleFromByteArray(result.Content, start, (DataFormat)device.DataFormat);
        //                        break;
        //                    case "STRING":
        //                        variable.VarValue = StringLib.GetStringFromByteArrayByEncoding(result.Content, start, (int)variable.Offset * 2, Encoding.ASCII);
        //                        break;
        //                    case "BYTEARRAY":
        //                        variable.VarValue = ByteArrayLib.GetByteArrayFromByteArray(result.Content, start, (int)variable.Offset * 2);
        //                        break;
        //                    default:
        //                        break;
        //                }

        //                var operateResult = MigrationLib.GetMigrationValue(variable.VarValue, variable.Scale.ToString(), variable.Offset.ToString());

        //                if (operateResult.IsSuccess)
        //                {
        //                    variable.VarValue = operateResult.Content;
        //                }
        //                else
        //                {
        //                    variable.VarValue = null;
        //                }

        //                //更新报警
        //                device.Update(variable);
        //            }
        //            else
        //            {
        //                return OperateResult.CreateFailResult(analysis.Message);
        //            }
        //        }
        //    }
        //    else
        //    {
        //        CommonMethods.Statues = new List<bool> { false, false, false, false };
        //        return OperateResult.CreateFailResult($"{group.GroupName}-通信组读取失败");
        //    }
        //    return OperateResult.CreateSuccessResult();
        //}


        /// <summary>
        /// 解析起始地址，获取索引 和 位偏移
        /// </summary>
        /// <param name="start">0 1 2  10.0 10.10</param>
        /// <param name="frombase"></param>
        /// <returns></returns>
        //private OperateResult<int, int> AnalysisStartAddress(string start, int frombase = 10)
        //{
        //    try
        //    {
        //        if (start.Contains("."))
        //        {
        //            string[] result = start.Split('.');

        //            if (result.Length == 2)
        //            {
        //                return OperateResult.CreateSuccessResult(Convert.ToInt32(result[0], frombase), Convert.ToInt32(result[1]));
        //            }
        //            else
        //            {
        //                return OperateResult.CreateFailResult<int, int>($"变量地址格式填写不正确：{start}");
        //            }
        //        }
        //        else
        //        {
        //            return OperateResult.CreateSuccessResult<int, int>(Convert.ToInt32(start, frombase), 0);
        //        }
        //    }
        //    catch (Exception ex)
        //    {
        //        return OperateResult.CreateFailResult<int, int>($"变量地址 {start} 格式填写不正确：" + ex.Message);
        //    }
        //}
        #endregion

        #region 加载设备信息
        private OperateResult<Device> LoadDevice(string devicepath, string groupPath, string variablePath)
        {
            if (!File.Exists(devicepath))
            {
                CommonMethods.AddLog(true, "设备文件不存在");
                return null;
            }
            Device device = new Device();
            List<Group> gpList = LoadGroup(groupPath, variablePath);
            if (gpList != null && gpList.Count > 0)
            {
                try
                {
                    device.IPAddress = IniConfigHelper.ReadIniData("设备参数", "IP地址", "127.0.0.1", devicepath);
                    device.Port = Convert.ToInt32(IniConfigHelper.ReadIniData("设备参数", "端口号", "502", devicepath));
                    device.PLCType = IniConfigHelper.ReadIniData("设备参数", "PLC类型", "OmronFinsTcp_HSL", devicepath);

                    CommonMethods.mesConfig.siteCode = IniConfigHelper.ReadIniData("MES配置", "工厂代码", "1");
                    CommonMethods.mesConfig.lineCode = IniConfigHelper.ReadIniData("MES配置", "产线编号", "1");
                    CommonMethods.mesConfig.equipNum = IniConfigHelper.ReadIniData("MES配置", "设备编号", "1");
                    device.GroupList = gpList;
                    return OperateResult.CreateSuccessResult(device);
                }
                catch (Exception ex)
                {
                    return OperateResult.CreateFailResult<Device>("请检查配置文件是否正确");
                }
            }
            else
            {
                return OperateResult.CreateFailResult<Device>("请检查配置是否包含欧姆龙PLC");
            }
        }

        ///// <summary>
        ///// 通信组及通信变量的解析
        ///// </summary>
        ///// <param name="groupPath"></param>
        ///// <param name="variablePath"></param>
        ///// <returns></returns>
        private List<Group> LoadGroup(string groupPath, string variablePath)
        {
            //判断文件是否存在
            if (!File.Exists(groupPath))
            {
                CommonMethods.AddLog(true, "通信组文件不存在");
                return null;
            }
            if (!File.Exists(variablePath))
            {
                CommonMethods.AddLog(true, "通信变量文件不存在");
                return null;
            }

            //先解析通信组
            List<Group> GpList = null;
            try
            {
                GpList = MiniExcelLibs.MiniExcel.Query<Group>(groupPath).ToList();
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, $"通信组加载失败：{ex.Message}");
                return null;
            }

            List<Variable> VarList = null;
            try
            {
                VarList = MiniExcelLibs.MiniExcel.Query<Variable>(variablePath).ToList();
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, $"通信变量加载失败：{ex.Message}");
                return null;
            }

            if (GpList != null && VarList != null)
            {
                foreach (var group in GpList)
                {
                    group.VarList = VarList.FindAll(c => c.GroupName == group.GroupName).ToList();
                }
                return GpList;
            }
            else
            {
                return null;
            }
        }
        #endregion

        #region 屏蔽 
        /// <summary>
        /// 读取配置文件，返回设备对象
        /// </summary>
        /// <param name="path"></param>
        /// <returns></returns>
        /// 
        //private OperateResult<OmronDevice> GetDeviceByPath(string path)
        //{
        //    List<Project> projects = new ConfigManage().LoadProjects(path);

        //    if (projects != null && projects.Count >= 1)
        //    {
        //        Project project = projects[0];

        //        if (project.OmronList.Count > 0)
        //        {
        //            var device = project.OmronList[0];

        //            if (device.IsActive)
        //            {
        //                return OperateResult.CreateSuccessResult(device);
        //            }
        //            else
        //            {
        //                return OperateResult.CreateFailResult<OmronDevice>("请检查配置是否激活");
        //            }
        //        }
        //        else
        //        {
        //            return OperateResult.CreateFailResult<OmronDevice>("请检查配置是否包含欧姆龙PLC");
        //        }
        //    }
        //    else
        //    {
        //        return OperateResult.CreateFailResult<OmronDevice>("请检查配置文件是否正确");
        //    }

        //}
        #endregion

        #endregion

        #region 定时刷新数据

        int TotalNum = 0;
        int Regular = 0;

        bool firstFresh = false;
        bool freshed = false;
        private void Timer_RefreshData_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
        {
            var nowDate = DateTime.Now;

            if (Regular >= 300)
            {
                Task.Run(() =>
                {
                    UploadEquEnergy();//电表
                    //UPloadAnemograph();//风速仪
                });
                Regular = 0;
            }
            if (TotalNum > 4)
            {
                GetEnergyData();
                Refresh12HourProdQty();
                GetDefectTypeQty();
                ReadPLCComm();
                //ClearNGData0();
                GetASqlAlarmData(DateTime.Today, CommonMethods.strClass);
                TotalNum = 0;
            }
            else if (TotalNum == 2)//设备状态读取
            {
                SetClass(); //变更班次
            }

            Task.Run(() =>
            {
                if (CommonMethods.plcDevice.IsConnected)
                {
                    //PingEMCLink();
                }
                ShowStateEven_Run();
            });


            TotalNum++;
            Regular++;
        }
        #endregion

        #region 服务器连接状态检测
        /// <summary>
        /// 服务器连接状态检测
        /// </summary>
        bool isNgral = false;
        //private void PingEMCLink()
        //{
        //    try
        //    {
        //        string ipAddress = CommonMethods.mesConfig.RotueServerIP; // 要 ping 的 IP 地址

        //        Ping pingSender = new Ping();
        //        PingReply reply = pingSender.Send(ipAddress);

        //        if (reply.Status == IPStatus.Success)
        //        {
        //            CommonMethods.EMCStatues = true;

        //            if (!isNgral)
        //            {
        //                if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
        //                {
        //                    JYResult result = CommonMethods.PlcLink.WriteValue("D80", 0, Data_Type.Short);//反馈PLC结果
        //                }
        //                CommonMethods.AddDataMonitorLog(0, $"服务器连接成功！");
        //                LogHelper.Instance.WriteLog($"服务器连接成功！");
        //                isNgral = true;
        //            }
        //        }
        //        else
        //        {
        //            CommonMethods.EMCStatues = false;
        //            if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
        //            {
        //                JYResult result = CommonMethods.PlcLink.WriteValue("D80", 1, Data_Type.Short);//反馈PLC结果
        //            }
        //            //CommonMethods.AddDataMonitorLog(1, $"服务器连接失败!解决办法：1、请检查MES网络，2、查看服务器是否正常！");
        //            LogHelper.Instance.WriteError($"服务器连接失败!", "系统报错");
        //            isNgral = true;
        //            //new MsgshowTip("与数据服务器链接断开!\n请检查MES网络或存储服务器！").ShowDialog();
        //        }

        //    }
        //    catch (Exception ex)
        //    {
        //        CommonMethods.EMCStatues = false;
        //        if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
        //        {
        //            JYResult result = CommonMethods.PlcLink.WriteValue("D80", 1, Data_Type.Short);//反馈PLC结果
        //        }

        //        //CommonMethods.AddDataMonitorLog(1, $"服务器连接失败!解决办法：1、请检查MES网络，2、查看服务器是否正常！");
        //        LogHelper.Instance.WriteError($"服务器连接失败!{ex}", "系统报错");
        //        isNgral = false;
        //        //new MsgshowTip("与数据服务器链接断开!\n请检查MES网络或存储服务器！").ShowDialog();
        //    }

        //}
        #endregion


        #region 设备综合信息
        /// <summary>
        /// 读取PLC通用信息
        /// </summary>
        internal void ReadPLCComm()
        {
            if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
            {
                Task.Run(() =>
                {
                    UpTotalCount(null);
                });

                CommonMethods.TotalQty = CommonMethods.PlcLink.ReadInt32("D15");//生产总数
                CommonMethods.ProOKQty = CommonMethods.PlcLink.ReadInt32("D17");//良品总数

                CommonMethods.Ppm = CommonMethods.PlcLink.ReadInt32("D13");
                //CommonMethods.JiaDL = Convert.ToDouble(CommonMethods.PlcLink.ReadFloat("D11").ToString("F2"))/100;
                CommonMethods.JiaDL = Convert.ToDouble(CommonMethods.PlcLink.ReadInt32("D11").ToString("F2")) / 100;

                #region 开机时间/运行时间
                CommonMethods.PlcOpenAndRunTime = GetList<int>(6, 0);
                JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>($"D50", Data_Type.ArrByte, 12);
                if (resByte.IsSuccess)
                {
                    for (int i = 0; i < CommonMethods.PlcOpenAndRunTimeAdress.Count; i++)
                    {
                        CommonMethods.PlcOpenAndRunTime[i] = ShortLib.GetShortFromByteArray(resByte.Content, i * 4, DataFormat.CDAB);
                    }
                }
                #endregion
            }

        }
        #endregion

        #region 保存12小时产能数据
        public int totalNum = 0;    // 总数
        public int okNum = 0;       // 良品数

        /// <summary>
        /// 储存数据到数据库
        /// </summary>
        /// <param name="DataCount"></param>
        public void UpTotalCount(int[] DataCount)
        {
            string strErr = "";
            DateTime dateTime = DateTime.Now;
            string strDate = dateTime.ToString("yyyy-MM-dd");
            int Min = dateTime.Minute;
            int Hour = dateTime.Hour;
            if (Min < 30)
            {
                Hour -= 1;
            }
            if (dateTime.Hour < 30 && dateTime.Hour == 0)
            {
                Hour = 0;
            }

            //读取PLC投入总数
            int ProdCurrAllQty = GetToDayHourQty(Hour, true);
            //读取PLC产出数
            int ProdCurrOKQty = GetToDayHourQty(Hour, false);
            Hourprod mh = new Hourprod();

            mh.FDate = strDate;
            mh.FHour = Hour;
            mh.ProdIn = ProdCurrAllQty;
            mh.ProdOut = ProdCurrOKQty;
            mh.TestTime = DateTime.Now;
            mh.Ppm = CommonMethods.Ppm;
            mh.JiaDL = Convert.ToDecimal(CommonMethods.JiaDL);

            //更新
            int res = CommonMethods.db.UpdateSingle(mh, it => new Hourprod() { ProdIn = mh.ProdIn, ProdOut = mh.ProdOut, TestTime = DateTime.Now, Ppm = mh.Ppm, JiaDL = mh.JiaDL, },
                it => it.FDate == mh.FDate && it.FHour == mh.FHour);
            if (res <= 0) //更新失败就新增保存
            {
                CommonMethods.db.AddReturnBool<Hourprod>(mh);
            }
            #region 屏蔽
            //    DateTime now = DateTime.Now;
            //    string day = now.ToString("yyyy-MM-dd HH:mm:ss");
            //    int Hour = 0;


            //    CommonMethods.LastHour = Convert.ToInt32(IniConfigHelper.ReadIniData("统计计数", "LastHour", "false"));
            //    CommonMethods.LastResetTime = IniConfigHelper.ReadIniData("统计计数", "LastResetTime", "false");
            //    CommonMethods.LastTotalNum = Convert.ToInt32(IniConfigHelper.ReadIniData("统计计数", "LastTotalOldNum", "false"));
            //    CommonMethods.LastOkNum = Convert.ToInt32(IniConfigHelper.ReadIniData("统计计数", "LastOkOldNum", "false"));


            //    if (now.Minute == 30 && (now.Second >= 0 && now.Second <= 3) && day != CommonMethods.LastResetTime)
            //    {
            //        // 每小时的0分0秒重置计数
            //        totalNum = 0;
            //        okNum = 0;
            //        CommonMethods.LastTotalNum = DataCount[0];
            //        CommonMethods.LastOkNum = DataCount[1];
            //        CommonMethods.LastResetTime = day;
            //        CommonMethods.LastHour = now.Hour;
            //        Hour = Convert.ToInt32($"{now.Hour}30");

            //        IniConfigHelper.WriteIniData("统计计数", "LastHour", CommonMethods.LastHour.ToString());
            //        IniConfigHelper.WriteIniData("统计计数", "LastResetTime", CommonMethods.LastResetTime);
            //        IniConfigHelper.WriteIniData("统计计数", "LastTotalOldNum", CommonMethods.LastTotalNum.ToString());
            //        IniConfigHelper.WriteIniData("统计计数", "LastOkOldNum", CommonMethods.LastOkNum.ToString());
            //    }
            //    else
            //    {
            //        // 读取PLC的数据（模拟数据）
            //        int[] productionData = DataCount;
            //        // 统计生产总数和良品数
            //        int newTotalNum = productionData[0] - CommonMethods.LastTotalNum;
            //        int newOkNum = productionData[1] - CommonMethods.LastOkNum;
            //        totalNum = newTotalNum;
            //        okNum = newOkNum;
            //        Hour = GetHour();
            //        // 计算百分比良率
            //    }

            //    Hourprod hourprod = new Hourprod();
            //    hourprod.FDate = now.Date.ToString("yyyy-MM-dd");
            //    hourprod.FHour = Hour;
            //    hourprod.ProdIn = totalNum;
            //    hourprod.ProdOut = okNum;
            //    hourprod.TestTime = now;

            //    //更新
            //    int res = CommonMethods.db.UpdateSingle(hourprod, it => new Hourprod() { ProdIn = hourprod.ProdIn, ProdOut = hourprod.ProdOut, TestTime = DateTime.Now },
            //        it => it.FDate == hourprod.FDate && it.FHour == hourprod.FHour);
            //    if (res == 0) //更新失败就新增保存
            //    {
            //        CommonMethods.db.AddReturnBool<Hourprod>(hourprod);
            //    }
            #endregion

        }


        /// <summary>
        /// 每小时产能读取处理
        /// </summary>
        /// <param name="hour"></param>
        /// <param name="flag"></param>
        /// <returns></returns>
        private int GetToDayHourQty(int hour, bool flag)
        {
            try
            {
                string strAddr = "";

                if (flag)//产出
                {
                    //strAddr = "D" + (1032 + hour);
                    //1257
                    strAddr = "D" + (1040 + hour);
                }
                else//良品数
                {
                    // strAddr = "D" + (1062 + hour);
                    //1257
                    strAddr = "D" + (1070 + hour);
                }
                int ProdNGQty = CommonMethods.PlcLink.ReadInt16(strAddr);
                return ProdNGQty;

            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message, "系统异常", MessageBoxButtons.OK, MessageBoxIcon.Hand);
            }
            return 0;
        }

        #endregion

        #region 5、设备状态
        /// <summary>
        /// 定时获取设备状态
        /// </summary>
        /// <param name="mt"></param>
        /// 
        int OldStatues = CommonMethods.mesConfig.DeviceState;       //默认状态是上一次退出程序是保存的状态
        int StatuesCount = 0;
        DateTime StatuesBeginTime = DateTime.Now.AddMinutes(-6);    //默认时间是6分钟前，第一次获取状态时上传设备状态,不赋默认值，第一次打开程序会导致时间为空，首次启动不上传设备状态
        bool isNewGuid = false;
        string strGuidAlarm = CommonMethods.mesConfig.guidStr;      //默认guid是上次退出程序保存的guid

        bool isUpIdle = false;
        List<AlarmData> AlarmDataTeam = new List<AlarmData>();
        bool run_AlarmMark = CommonMethods.mesConfig.m_run_AlarmMark;
        bool run_IdleMark = CommonMethods.mesConfig.m_run_IdelMark;
        private void ShowStateEven_Run()
        {
            try
            {
                #region 上传设备状态
                //设备状态 。Run：（正常运行）、Alert：（故障调试）、Idle：（闲置待机）、Maintain（停止运行）
                //先确定设备是在自动还是手动状态下
                if (CommonMethods.plcDevice != null && CommonMethods.plcDevice.IsConnected)
                {
                    string Date = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
                    bool isUpload = false;
                    string deviceStatus = string.Empty;
                    string deviceStatusDesc = string.Empty;
                    string strGuid = string.Empty;
                    short NewStatus = 100;
                    NewStatus = CommonMethods.PlcLink.ReadInt16("D10");
                    if (NewStatus != 100)
                    {
                        //新状态：故障，旧状态：正常
                        if (NewStatus == 3 && OldStatues == 1)
                        {
                            run_AlarmMark = true;
                            IniConfigHelper.WriteIniData("MES配置", "run_AlarmMark", "1");
                        }        //第一次进入报警状态，把报警标志位true
                                 //新状态：正常
                        if (NewStatus == 1)
                        {
                            run_AlarmMark = false;
                            IniConfigHelper.WriteIniData("MES配置", "run_AlarmMark", "0");
                        }      //如果状态变为允许，把报警标志位false
                        if (run_AlarmMark)
                        {
                            NewStatus = 3;
                        }   //有报警标志位，状态一直都是报警，直到下一次状态为运行

                        if (NewStatus == 4 && OldStatues == 1)
                        {
                            run_IdleMark = true;
                            IniConfigHelper.WriteIniData("MES配置", "run_IdleMark", "1");
                        }        //第一次进入闲置状态，把闲置标志位true
                        if (NewStatus == 1)
                        {
                            run_IdleMark = false;
                            IniConfigHelper.WriteIniData("MES配置", "run_IdleMark", "0");
                        }      //如果状态变为允许，把闲置标志位false
                        if (run_IdleMark)
                        {
                            NewStatus = 4;
                        }   //有闲置标志位，状态一直都是闲置，直到下一次状态为运行

                        if (isUpIdle)
                        {
                            foreach (var item in AlarmDataTeam)
                            {
                                UpIdleData(item);
                            }
                            isUpIdle = false;
                            AlarmDataTeam.Clear();
                        }


                        // 判断是否需要上传设备状态
                        if (NewStatus != OldStatues)
                        {
                            LogMessage("OldStatues: " + OldStatues + "; NewStatus: " + NewStatus + "上传的GUID：" + strGuidAlarm, "设备状态改变日志");
                            if (OldStatues == 3 && NewStatus != 3)
                            {
                                ShowAlarmEven_Run(strGuidAlarm);
                            }
                            OldStatues = NewStatus;
                            alarmStartDate = "";
                            isRead = false;
                            isUpload = true;
                            StatuesBeginTime = Convert.ToDateTime(Date);
                            strGuidAlarm = Guid.NewGuid().ToString();

                            //当设备状态发生变化，保存【设备状态和guid】到本地配置文件，下次电脑重启时读取上一次设备状态和guid
                            IniConfigHelper.WriteIniData("MES配置", "guid", strGuidAlarm.Trim());
                            IniConfigHelper.WriteIniData("MES配置", "DeviceState", OldStatues.ToString());
                        }
                        else
                        {
                            if (Convert.ToDateTime(Date).Subtract(StatuesBeginTime).TotalSeconds >= 5 * 60)     //时间间隔大雨5分钟
                            {
                                isUpload = true;
                                StatuesBeginTime = DateTime.Now;
                            }

                            //if (Convert.ToDateTime(Date).Subtract(StatuesBeginTime).TotalSeconds > 5 * 60)
                            //{
                            //    isUpload = true;
                            //    StatuesBeginTime = DateTime.Now;
                            //}
                        }
                        switch (NewStatus)
                        {
                            case 1:

                                CommonMethods.Statues = new List<bool> { true, false, false, false };
                                deviceStatus = "Run";
                                deviceStatusDesc = "正常运行";

                                if (isUpload)
                                {
                                    CommonMethods.AddLog(false, "正常运行");
                                }
                                break;
                            //case 2:
                            //    CommonMethods.Statues = new List<bool> { false, true, false, false };
                            //    deviceStatus = "Maintain";
                            //    deviceStatusDesc = "停止运行";
                            //    if (isUpload)
                            //    {
                            //        CommonMethods.AddLog(false, "停止运行");

                            //    }

                            //    break;
                            case 3:
                                CommonMethods.Statues = new List<bool> { false, false, true, false };
                                deviceStatus = "Alert";
                                deviceStatusDesc = "故障调试";
                                if (isUpload)
                                {
                                    CommonMethods.AddLog(false, "故障调试");

                                }

                                Task.Run(() =>
                                {
                                    ShowAlarmEven_Run(strGuidAlarm);
                                });
                                break;
                            case 4:
                                CommonMethods.Statues = new List<bool> { false, false, false, true };
                                deviceStatus = "Idle";
                                deviceStatusDesc = "闲置待机";

                                Task.Run(() =>
                                {
                                    ShowStuesEven_Run(Date, strGuidAlarm);
                                });
                                if (isUpload)
                                {
                                    CommonMethods.AddLog(false, "闲置待机");
                                }

                                break;
                            default:
                                break;
                        }

                        if (CommonMethods.sysConfig.MesModeSwitching)
                        {
                            if (isUpload && (NewStatus == 1 || NewStatus == 3 || NewStatus == 4))//|| NewStatus == 2
                            {
                                MESDataCombin.EqpStatusParam(deviceStatus, Date, strGuidAlarm, null);

                                StatuesBeginTime = DateTime.Now;
                            }
                        }
                    }
                }
                #endregion
            }
            catch (Exception ex)
            {
                LoggerHelp.WriteEX(ex);
            }
        }

        #region 触摸屏弹窗
        private void ShowStuesEven_Run(string Date, string strGuid)
        {
            if (CommonMethods.plcDevice.IsConnected)
            {
                string strCode = "";
                string strText = "";
                short HMIStatus = CommonMethods.PlcLink.ReadInt16("D40");
                if (HMIStatus != 0)
                {
                    CommonMethods.AddDataMonitorLog(0, "触发了手动HMI弹窗功能！");
                    switch (HMIStatus)   //注意：B1-D12都为闲置代码，上传代码是只需上传闲置代码
                    {
                        case 1:
                            strCode = "B1";
                            CommonMethods.AddDataMonitorLog(0, "B1 计划维护");

                            break;
                        case 2:
                            strCode = "B2";
                            CommonMethods.AddDataMonitorLog(0, "B2 无计划生产");
                            break;
                        case 3:
                            strCode = "B3";
                            CommonMethods.AddDataMonitorLog(0, "B3 样品测试");
                            break;
                        case 4:
                            strCode = "B4";
                            CommonMethods.AddDataMonitorLog(0, "B4.其他计划停机");
                            break;
                        case 5:
                            strCode = "D1";
                            CommonMethods.AddDataMonitorLog(0, "D1 设备故障");
                            break;
                        case 6:
                            strCode = "D2";
                            CommonMethods.AddDataMonitorLog(0, "D2.设备换型");
                            break;
                        case 7:
                            strCode = "D3";
                            CommonMethods.AddDataMonitorLog(0, "D3 工程变更");
                            break;
                        case 8:
                            strCode = "D4";
                            CommonMethods.AddDataMonitorLog(0, "D4.MES停机");
                            break;
                        case 9:
                            strCode = "D5";
                            CommonMethods.AddDataMonitorLog(0, "D5.来料异常");
                            break;
                        case 10:
                            strCode = "D6";
                            CommonMethods.AddDataMonitorLog(0, "D6.选择配件/物料异常");
                            break;
                        case 11:
                            strCode = "D7";
                            CommonMethods.AddDataMonitorLog(0, "D7.来料不良");
                            break;
                        case 12:
                            strCode = "D8";
                            CommonMethods.AddDataMonitorLog(0, "D8.待料");
                            break;
                        case 13:
                            strCode = "D9";
                            CommonMethods.AddDataMonitorLog(0, "D9.品质检查");
                            break;
                        case 14:
                            strCode = "D10";
                            CommonMethods.AddDataMonitorLog(0, "D10.清洁检点");
                            break;
                        case 15:
                            strCode = "D11";
                            CommonMethods.AddDataMonitorLog(0, "D11.环境不足");
                            break;
                        case 16:
                            strCode = "D12";
                            CommonMethods.AddDataMonitorLog(0, "D12.非计划停机");
                            break;
                        default:
                            break;
                    }

                    if (CommonMethods.mesConfig.isUpMes)
                    {
                        AlarmData alarmData = new AlarmData();
                        alarmData.AlarmCode = strCode;
                        alarmData.StartTime = Date;
                        alarmData.EndTime = "";
                        alarmData.AlarmType = "非计划损失";
                        alarmData.AlarmContent = strText;
                        alarmData.AlarmGuid = strGuid;

                        AlarmDataTeam.Add(alarmData);
                        isUpIdle = true;
                        string resJson = MESDataCombin.EquAlarm(alarmData, 0);
                        var result = JsonConvert.DeserializeObject<MesResponse>(resJson);
                        if (result.success)
                            CommonMethods.AddDataMonitorLog(0, $"HMI手动弹窗状态开始已上传成功,代码：{strCode}");
                        bool IsSuccesss = CommonMethods.PlcLink.WriteInt16("D40", 0);
                        if (IsSuccesss)
                            CommonMethods.AddDataMonitorLog(0, $"D40已复位0");
                    }
                    else
                    {
                        CommonMethods.AddDataMonitorLog(0, $"MES未在线,HMI手动弹窗状态未上传,代码：{strCode}");
                        bool IsSuccesss = CommonMethods.PlcLink.WriteInt16("D40", 0);
                        if (IsSuccesss) { CommonMethods.AddDataMonitorLog(0, $"D40已复位0"); }
                        else { CommonMethods.AddDataMonitorLog(0, $"D40未复位0"); }
                    }
                }
            }
        }
        #endregion

        private void UpIdleData(AlarmData alarmData)
        {
            if (alarmData == null) { return; }
            alarmData.EndTime = DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss");

            string resJson = MESDataCombin.EquAlarm(alarmData, 0);
            var result = JsonConvert.DeserializeObject<MesResponse>(resJson);
            if (result.success)
                CommonMethods.AddDataMonitorLog(0, $"HMI手动弹窗状态结束已上传成功,代码：{alarmData.AlarmCode}");
        }
        #endregion

        #region 6、设备报警
        //报警表单数据
        List<AlarmForm> listAlarmForm = null;
        public void GetAlarmData()
        {
            //加载PLC报警文件
            try
            {
                string strFileName = System.Environment.CurrentDirectory + "\\欧姆龙报警寄存器对应表.csv";
                listAlarmForm = CSVHelper<AlarmForm>.ReadCSV(strFileName);
            }
            catch (Exception ex)
            {
                MessageBox.Show("加载报警文件失败！");
            }

        }

        /// <summary>
        /// 报警信息读取
        /// </summary>
        /// <param name="mt"></param>
        /// <param name="resByte"></param>
        List<AlarmData> listOld = new List<AlarmData>();
        List<AlarmData> listNew = new List<AlarmData>();
        List<AlarmStatus> listAlarmStatus = null;
        string alarmStartDate = "";
        int AlarmCount = 0;
        string strAllAlarm = "";
        bool isRead = false;
        private void ShowAlarmEven_Run(string strGuidAlarm)
        {
            if (CommonMethods.IsRun && CommonMethods.plcDevice.IsConnected)
            {
                //StringBuilder sb = new StringBuilder();
                listNew.Clear();
                string Date = DateTime.Now.ToString("yyyy/MM/dd HH:mm:ss");
                JYResult<byte[]> resByte = CommonMethods.PlcLink.ReadValue<JYResult<byte[]>>("D10010", Data_Type.ArrByte, 500);
                if (resByte.IsSuccess && resByte != null)
                {
                    if (resByte == null) { return; }
                    //如果未配置报警地址信息返回 TODO
                    if (listAlarmForm == null) { return; }
                    int startPlcAddr = 10010;//TODO 读取起始地址
                    //3.公用方法解析byte[]数据 => List<AlarmStatus>           
                    if (resByte == null) { return; } //如果未配置报警地址信息返回
                    //TODO 切换三菱和欧姆龙
                    listAlarmStatus = PLCAlarmParseHelper.OmronFinsByte2Status(startPlcAddr, resByte.Content);
                    //4.判定有不良后，关联AlarmStatus 和AlarmForm
                    if (listAlarmStatus == null) { return; } //状态信息为空返回
                                                             //如果有报警，获取报警信息
                    if (listAlarmStatus.Any(p => p.Status))
                    {
                        //关联表单数据和报警记录，获取报警信息
                        listNew = listAlarmStatus
                         .Where(s => s.Status)
                         .Join(listAlarmForm
                         , s => s.PLCAdress
                         , f => f.PLCAdress
                         , (s, f) => new AlarmData()
                         {
                             AlarmGuid = strGuidAlarm,
                             PLCAdress = s.PLCAdress,
                             AlarmCode = f.AlarmCode,
                             AlarmContent = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
                             AlarmType = "停机报警",
                             AlarmDesc = f.AlarmContent == "" ? s.PLCAdress : f.AlarmContent,
                             AlarmState = "1",
                             StartTime = Date,
                             EndTime = Date,
                             Flag = 0
                         }).ToList();
                    }

                    string strAlarm = "";
                    //添加新的报警信息
                    if (listNew.Count > 0)
                    {
                        if (!isRead)
                        {
                            alarmStartDate = Date;
                            isRead = true;
                        }

                        strAllAlarm = "";
                        listNew.ForEach(r =>
                        {
                            strAllAlarm += $"{r.AlarmContent},";

                            var alarmLog = listOld.FirstOrDefault(o => o.PLCAdress == r.PLCAdress);
                            if (alarmLog == null)
                            {
                                listOld.Add(r);
                                //上传报警
                                if (CommonMethods.sysConfig.MesModeSwitching)
                                {
                                    //上传报警
                                    MESDataCombin.EquAlarm(r, 1);
                                }
                                //显示报警信息
                                CommonMethods.ShowAlarmLog(r.AlarmContent);
                            }
                        });
                    }

                    //显示报警信息
                    //strAlarm = sb.ToString();
                    if (strAllAlarm != "")
                    {
                        CommonMethods.SlideAlarmText = strAllAlarm.Substring(0, strAllAlarm.Length - 1);
                    }

                    //移除已经消除的报警信息
                    var saveAlarmData = new List<AlarmData>();
                    var listOldAlarm = new List<AlarmData>();
                    listOldAlarm.AddRange(listOld);
                    if (listOldAlarm.Count > 0)
                    {
                        foreach (var item in listOldAlarm)
                        {
                            var alarmLog = listNew.FirstOrDefault(n => n.PLCAdress == item.PLCAdress);
                            if (alarmLog == null)
                            {
                                item.EndTime = Date;
                                saveAlarmData.Add(item);
                                listOld.Remove(item);
                            }
                        }
                    }

                    if (saveAlarmData.Count > 0)
                    {
                        string strALLAlarm = "";
                        //写csv文件
                        var nowDate = DateTime.Now;
                        string basePath = $@"{CommonMethods.strAlarmLogspath}\{DateTime.Now.Year}\{DateTime.Now.Month}";
                        string fileName = $@"{nowDate.Day}.csv";
                        string title = "GUID,报警地址,故障代码,报警内容,开始时间,结束时间,是否停机";
                        string alarmContent = string.Empty;

                        List<FaultCodeList> faultCodeLists = new List<FaultCodeList>();
                        foreach (var m in saveAlarmData)
                        {
                            FaultCodeList item = new FaultCodeList();
                            item.faultCode = m.AlarmCode;
                            faultCodeLists.Add(item);
                            alarmContent += $"{m.AlarmGuid},{m.PLCAdress},{m.AlarmCode},{m.AlarmContent},{m.StartTime},{m.EndTime},{m.AlarmType}\n";
                            strALLAlarm += $"{m.AlarmContent},";

                            //上传报警
                            if (CommonMethods.sysConfig.MesModeSwitching)
                            {
                                //上传报警
                                MESDataCombin.EquAlarm(m, 0);
                            }
                        }

                        alarmContent = alarmContent.Substring(0, alarmContent.Length - 1);
                        CSVHelper<AlarmCSVData>.WriterCSV(basePath, fileName, title, alarmContent);

                        // 上传消除的报警信息
                        if (CommonMethods.sysConfig.MesModeSwitching)
                        {
                            //上传设备报警状态
                            MESDataCombin.EqpStatusParam("Alert", string.IsNullOrEmpty(alarmStartDate) ? Date : alarmStartDate, strGuidAlarm, faultCodeLists);
                        }
                        //报警保存
                        SaveAlarmCount(saveAlarmData);
                    }
                }
            }
        }


        /// <summary>
        /// 报警保存
        /// </summary>
        private void SaveAlarmCount(List<AlarmData> alarmDatas)
        {
            bool ISAdd = false;
            var recordToUpdate = new AlarmCountEntry();

            DateTime today = DateTime.Today;
            DateTime upTime = DateTime.Now;
            var listAlarmStatistics = CommonMethods.db.QueryWhereList<AlarmCountEntry>(it => Convert.ToDateTime(it.AlarmTime.ToString("yyyy-MM-dd")) == today);
            List<AlarmCountEntry> fd = new List<AlarmCountEntry>();
            if (listAlarmStatistics != null)
            {
                alarmDatas.ForEach(r =>
                {
                    recordToUpdate = listAlarmStatistics.FirstOrDefault(x => x.PLCAdress.Trim() == r.PLCAdress);
                    if (recordToUpdate != null)
                    {
                        CommonMethods.db.Update<AlarmCountEntry>(it => it.AlarmCount == it.AlarmCount + 1, it => it.PLCAdress == r.PLCAdress && Convert.ToDateTime(it.AlarmTime.ToString("yyyy-MM-dd")) == today);
                    }
                    else
                    {
                        ISAdd = true;
                        AlarmCountEntry alarm = new AlarmCountEntry();
                        alarm.PLCAdress = r.PLCAdress;
                        alarm.AlarmContent = r.AlarmContent;
                        alarm.AlarmCount = 1;
                        alarm.Class = CommonMethods.strClass;
                        alarm.AlarmTime = upTime;
                        fd.Add(alarm);
                    }

                });
                if (ISAdd)
                {
                    bool res = CommonMethods.db.AddReturnBool(fd);

                    ISAdd = false;
                }

            }
            else
            {
                foreach (var m in listNew)
                {
                    AlarmCountEntry alarm = new AlarmCountEntry();
                    alarm.PLCAdress = m.PLCAdress;
                    alarm.AlarmContent = m.AlarmContent;
                    alarm.AlarmCount = 1;
                    alarm.Class = CommonMethods.strClass;
                    alarm.AlarmTime = today;
                    fd.Add(alarm);
                }
                CommonMethods.db.AddReturnBool(fd);
            }


            GetASqlAlarmData(DateTime.Today, CommonMethods.strClass);
        }


        /// <summary>
        /// 读取数据库报警信息
        /// </summary>
        /// <param name="today"></param>
        /// <param name="strClass"></param>
        public void GetASqlAlarmData(DateTime today, string strClass)
        {
            try
            {
                List<ChartDataType> chartAlarms = new List<ChartDataType>();
                List<AlarmCountEntry> AlarmDatas = null;
                List<string> List_X = new List<string>();
                List<int> List_Y = new List<int>();

                DateTime baiClassStart = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 8:30:00"));
                DateTime baiClassEnd = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 20:29:59"));

                DateTime yeClassStart = Convert.ToDateTime(DateTime.Now.ToString("yyyy-MM-dd 20:30:00"));
                DateTime yeClassEnd = Convert.ToDateTime(DateTime.Now.AddDays(1).ToString("yyyy-MM-dd 8:29:59"));


                if (strClass == "全天")
                {
                    AlarmDatas = CommonMethods.db.QueryList<AlarmCountEntry>("AlarmCount", 10, it => Convert.ToDateTime(it.AlarmTime.ToString("yyyy-MM-dd")) == today);
                }
                else if (strClass == "白班")
                {
                    AlarmDatas = CommonMethods.db.QueryList<AlarmCountEntry>("AlarmCount", 10, it => it.AlarmTime >= baiClassStart && it.AlarmTime <= baiClassEnd && it.Class == strClass);
                }
                else
                {
                    AlarmDatas = CommonMethods.db.QueryList<AlarmCountEntry>("AlarmCount", 10, it => it.AlarmTime >= yeClassStart && it.AlarmTime <= yeClassEnd && it.Class == strClass);

                }

                if (AlarmDatas != null && AlarmDatas.Count > 0)
                {

                    for (int i = 0; i < AlarmDatas.Count; i++)
                    {
                        chartAlarms.Add(new ChartDataType()
                        {
                            DataType = AlarmDatas[i].AlarmContent,
                            DataCount = (int)AlarmDatas[i].AlarmCount
                        });
                    }



                    CommonMethods.Lst_AlarmTop10_Qty = chartAlarms;
                }
                else
                {
                    CommonMethods.Lst_AlarmTop10_Qty = null;
                }
            }
            catch (Exception)
            {

            }
        }

        #endregion

        #region 获取白夜班次
        bool qiehuan = false;
        bool Yeqiehuan = false;
        private void SetClass()
        {
            try
            {
                var nowDate = DateTime.Now;
                string strClass = "";
                DateTime time1 = Convert.ToDateTime($"{nowDate.ToShortDateString()} {CommonMethods.ChangeClassTime}");
                DateTime time2 = Convert.ToDateTime($"{nowDate.ToShortDateString()} {Convert.ToDateTime(CommonMethods.ChangeClassTime).AddHours(12).ToString("HH:mm:ss")}");
                if (nowDate <= time1 && nowDate >= time2)
                {
                    Yeqiehuan = false;
                    if (CommonMethods.plcDevice.IsConnected)
                    {
                        if (!qiehuan)
                        {
                            if (!SetPlcTime())
                            {
                                CommonMethods.AddLog(true, $"PC写入PLC时间失败！");
                            }
                            else
                            {
                                qiehuan = true;
                                CommonMethods.AddLog(false, "PC写入PLC时间成功！");
                            }
                        }
                    }
                    strClass = "白班";
                }
                else
                {
                    qiehuan = false;
                    if (!Yeqiehuan || (nowDate.Hour == 0 && nowDate.Minute == 0 && nowDate.Second > 45))
                    {
                        if (!SetPlcTime())
                        {
                            CommonMethods.AddLog(true, $"PC写入PLC时间失败！");
                        }
                        else
                        {
                            Yeqiehuan = true;
                            CommonMethods.AddLog(false, "PC写入PLC时间成功！");
                        }
                    }
                    strClass = "夜班";
                }
                CommonMethods.strClass = strClass;
            }
            catch (Exception ex)
            {
                CommonMethods.AddLog(true, "设备状态" + ex.Message);
                LoggerHelp.WriteEX(ex);
            }
        }
        #endregion

        #region  写入PLC时间
        /// <summary>
        /// 写当前时间给PLC
        /// </summary>
        private bool SetPlcTime()
        {
            var nowDate = DateTime.Now;
            int nowSec = nowDate.Second;
            while (nowSec == nowDate.Second)
                nowDate = DateTime.Now;
            string yearStr = nowDate.Year.ToString();

            //byte year = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(yearStr), 1);
            //byte month = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Month.ToString("00")), 0);
            //byte day = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Day.ToString("00")), 0);
            //byte hour = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Hour.ToString("00")), 0);
            //byte minute = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Minute.ToString("00")), 0);
            //byte second = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.Second.ToString("00")), 0);
            //byte week = ByteLib.GetByteFromByteArray(Encoding.UTF8.GetBytes(nowDate.DayOfWeek.ToString("00")), 0);


            //List<byte> byteList = new List<byte> {
            //        // FinsTcp Header
            //        0x46, 0x49, 0x4E, 0x53,  // FINS  Ascii编码
            //        0x00,0x00,0x00,0x1B,   // 后续字节数
            //        0x00,0x00,0x00,0x02,   // Command:客户端（上位机）连接到服务端（PLC）
            //        0x00,0x00,0x00,0x00,   // 错误码：表示无错误
            //                               // Fins Header
            //        0x80,
            //        0x00,
            //        0x02,
            //        0x00,DA1,0x00,
            //        0x00,SA1,0x00,
            //        0xFF,  // SID

            //        // Command
            //        0x07,0x02,  // 表示读取PLC时间
            //        // 年、月、日、时、分、秒  星期
            //        year,month,day,hour,minute,second,week
            //    };
            bool IsSuccess = false;

            // 为防止PLC时间出现偏差，每次自动运行的时候写PLC系统时间
            short[] writeArr = new short[]
            {
        Convert.ToInt16(nowDate.Year),//D70
        Convert.ToInt16(nowDate.Month),//D71
        Convert.ToInt16(nowDate.Day),//D72
        Convert.ToInt16(nowDate.Hour),//D73
        Convert.ToInt16(nowDate.Minute),//D74
        Convert.ToInt16(nowDate.Second + 1),//D75
        (short)1 //D76
            };
            if (CommonMethods.plcDevice.IsConnected)
            {
                JYResult result = CommonMethods.PlcLink.WriteValue("D70", writeArr, Data_Type.ArrShort);
                if (result.IsSuccess)
                {
                    IsSuccess = true;
                }
            }
            return IsSuccess;

        }
        #endregion
    }
}
